<template>
  <div class="pdf-container">
    <!-- 搜索框 -->
    <div class="search-box">
      <input v-model="searchText" placeholder="输入搜索内容" @keyup.enter="performSearch">
      <button @click="performSearch">
        搜索
      </button>
      <span v-if="matches.length > 0">
        {{ currentMatchIndex + 1 }} / {{ matches.length }}
      </span>
      <button :disabled="matches.length === 0" @click="prevMatch">
        上一个
      </button>
      <button :disabled="matches.length === 0" @click="nextMatch">
        下一个
      </button>
    </div>

    <!-- PDF 显示区域 -->
    <div ref="pdfViewer" class="pdf-viewer">
      <div v-for="page in pages" :key="page.pageNumber" class="pdf-page-container">
        <canvas :ref="`canvas-${page.pageNumber}`" />
        <div class="text-layer" :style="{
            width: page.viewport.width + 'px',
            height: page.viewport.height + 'px',
          }">
          <span v-for="(textItem, index) in page.textContent.items" :key="index" class="text-span"
            :style="getTextItemStyle(textItem)">{{ textItem.str }}</span>
        </div>
        <div class="highlight-layer" :style="{
            width: page.viewport.width + 'px',
            height: page.viewport.height + 'px',
          }">
          <div v-for="(match, index) in getMatchesForPage(page.pageNumber)" :key="index" class="highlight"
            :style="getHighlightStyle(match)" />
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import pdfjsLib from 'pdfjs-dist/build/pdf'
import pdfjsWorker from 'pdfjs-dist/build/pdf.worker.entry'

pdfjsLib.GlobalWorkerOptions.workerSrc = pdfjsWorker

export default {
  data() {
    return {
      pdfDoc: null,
      pages: [],
      searchText: '',
      matches: [],
      currentMatchIndex: -1
    }
  },

  mounted() {
    // 加载示例 PDF（替换为你的 PDF 路径）
    this.loadPdf('http://192.168.2.108:8080/pdf/data/653788/4c008b6348ba6d47ed7b966982a03d7a_doublelayer.pdf')
  },

  methods: {
    async loadPdf(url) {
      const loadingTask = pdfjsLib.getDocument(url)
      this.pdfDoc = await loadingTask.promise

      this.pages = []
      for (let i = 1; i <= this.pdfDoc.numPages; i++) {
        const page = await this.pdfDoc.getPage(i)
        const viewport = page.getViewport({ scale: 1.5 })

        // 渲染 Canvas
        const canvas = this.$refs[`canvas-${i}`][0]
        const context = canvas.getContext('2d')
        canvas.height = viewport.height
        canvas.width = viewport.width

        await page.render({
          canvasContext: context,
          viewport
        }).promise

        // 提取文本内容
        const textContent = await page.getTextContent()

        this.pages.push({
          pageNumber: i,
          viewport,
          textContent,
          pageInstance: page
        })
      }
    },

    getTextItemStyle(textItem) {
      const transform = `matrix(${textItem.transform.join(',')})`
      return {
        transform,
        left: textItem.transform[4] + 'px',
        top: textItem.transform[5] + 'px',
        fontSize: Math.sqrt(
          textItem.transform[0] * textItem.transform[0] +
          textItem.transform[1] * textItem.transform[1]
        ) + 'px'
      }
    },

    async performSearch() {
      this.matches = []

      for (const page of this.pages) {
        const textContent = await page.pageInstance.getTextContent()
        textContent.items.forEach((textItem, itemIndex) => {
          if (textItem.str.includes(this.searchText)) {
            this.matches.push({
              pageNumber: page.pageNumber,
              textItem,
              itemIndex
            })
          }
        })
      }

      if (this.matches.length > 0) {
        this.currentMatchIndex = 0
        this.scrollToMatch(this.matches[0])
      }
    },

    getMatchesForPage(pageNumber) {
      return this.matches.filter(m => m.pageNumber === pageNumber)
    },

    getHighlightStyle(match) {
      const textItem = match.textItem
      return {
        left: textItem.transform[4] + 'px',
        top: textItem.transform[5] + 'px',
        width: textItem.width + 'px',
        height: textItem.height + 'px'
      }
    },

    scrollToMatch(match) {
      const pageElement = this.$el.querySelector(
        `.pdf-page-container:nth-child(${match.pageNumber + 1})`
      )
      if (pageElement) {
        pageElement.scrollIntoView({ behavior: 'smooth' })
      }
    },

    nextMatch() {
      if (this.currentMatchIndex < this.matches.length - 1) {
        this.currentMatchIndex++
        this.scrollToMatch(this.matches[this.currentMatchIndex])
      }
    },

    prevMatch() {
      if (this.currentMatchIndex > 0) {
        this.currentMatchIndex--
        this.scrollToMatch(this.matches[this.currentMatchIndex])
      }
    }
  }
}
</script>

<style scoped>
.pdf-container {
  position: relative;
  max-width: 100%;
  overflow: auto;
}

.pdf-viewer {
  position: relative;
}

.pdf-page-container {
  position: relative;
  margin: 20px auto;
}

.text-layer {
  position: absolute;
  pointer-events: none;
  overflow: hidden;
  top: 0;
  left: 0;
}

.text-span {
  color: transparent;
  position: absolute;
  white-space: pre;
  cursor: text;
  transform-origin: 0% 0%;
}

.highlight-layer {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
}

.highlight {
  position: absolute;
  background-color: rgba(255, 255, 0, 0.3);
}

.search-box {
  position: sticky;
  top: 0;
  background: white;
  padding: 10px;
  z-index: 100;
}
</style>